#ifndef __FPS_CAP_HPP__
#define __FPS_CAP_HPP__

#include <chrono>
#include <iostream>
#include <mutex>
#include <numeric>
#include <thread>
#include <vector>

using namespace std;
using namespace std::chrono;

class FpsCap {
private:
  uint64_t time_stamp_now;
  uint64_t time_stamp_old = 0;
  uint32_t idx = 0;
  vector<uint64_t> dt_buf_;
  bool ok = false;
  mutex mtx_;

public:
  FpsCap(const int win_len) : dt_buf_(win_len ? win_len : 1, 0){};
  ~FpsCap(){};
  void sample() {
    time_stamp_now = get_time_since_epoch_in_ms();
    if (time_stamp_old) { // 第一次time_stamp_old=0 跳过
      mtx_.lock();
      dt_buf_[(idx++) % dt_buf_.size()] = time_stamp_now - time_stamp_old;
      mtx_.unlock();
    }
    time_stamp_old = time_stamp_now;
    if (idx == dt_buf_.size()) {
      ok = true; // 可以稳定输出
    }
  };

  double get_fps() {
    if (!ok)
      return 0.0;
    int total_time_ms = accumulate(dt_buf_.begin(), dt_buf_.end(), 0);
    return 1000.0 * dt_buf_.size() / (double)total_time_ms;
  };

  static uint64_t get_time_since_epoch_in_ms() {
    auto local_time = system_clock::now().time_since_epoch();
    return duration_cast<milliseconds>(local_time).count();
  };
  vector<uint64_t> get_dt_buf() { return vector<uint64_t>(dt_buf_); }
};

#endif // __FPS_CAP_HPP__